
#include <jni.h>
#include <assert.h>
#include <stdio.h>
#include <string.h>

#include <android/native_window_jni.h>
#include <android/log.h>

#include "com_wits_av_JniG711Encoder.h"
#include "G711Encoder.h"
#include "SharedPtr.h"
#include "TCriticalSection.h"

#include "JniHelper.h"
#include "CLog.h"



bool g_isInited = false;

JavaVM* g_Jvm = NULL;

jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
	__android_log_print(ANDROID_LOG_INFO, "jni", "--- JNI_OnLoad. G711Encoder vm:%p", vm);

	g_Jvm = vm;

	return JNI_VERSION_1_4;
}

void JNI_OnUnload(JavaVM *vm, void *reserved)
{

}



/*
 * Class:     com_wits_av_JniG711Encoder
 * Method:    g711_open
 * Signature: (III)I
 */
JNIEXPORT jint JNICALL Java_com_wits_av_JniG711Encoder_g711_1open
  (JNIEnv * env, jclass thiz, jint jcodec, jint jfreq, jint jchannels)
{
	__android_log_print(ANDROID_LOG_INFO, "jni", "g711_open");
	
	if (!g_isInited)
	{
		g711_init();
	}
	
	g711_t handle = -1;
	int rc = g711_open(&handle, jcodec, jfreq, jchannels);

	CLog::info("g711_open. handle: %d\n", handle);

	return handle;
}

/*
 * Class:     com_wits_av_JniG711Encoder
 * Method:    g711_close
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_com_wits_av_JniG711Encoder_g711_1close
  (JNIEnv * env, jclass thiz, jint jhandle)
{
	g711_close(jhandle);
}

/*
 * Class:     com_wits_av_JniG711Encoder
 * Method:    g711_encode
 * Signature: (I[BIJLcom/wits/av/MPacket;)I
 */
JNIEXPORT jint JNICALL Java_com_wits_av_JniG711Encoder_g711_1encode
  (JNIEnv * env, jclass thiz, jint jhandle, jbyteArray jdata, jint jlength, jlong jpts, jobject jpkt)
{
	MPacket pkt;
	memset(&pkt, 0, sizeof(pkt));
	
	jni::ByteArray byteArray(env, jdata);
	
	int rc = g711_encode(jhandle, (uint8_t*)byteArray.element(), byteArray.length(), jpts, &pkt);

	if (rc == 0)
	{
		jni::Object obj(env, "com/wits/av/MPacket", jpkt);
		obj.setInt("type", MTYPE_AUDIO);
		obj.setInt("duration", pkt.duration);
		obj.setInt("flags", pkt.flags);
		obj.setLong("pts", pkt.pts);

		jbyteArray data = env->NewByteArray(pkt.size);
		env->SetByteArrayRegion(data, 0, pkt.size, (const jbyte*)pkt.data);
		obj.setByteArray("data", data);
	}
	
	return rc;
}
  
  